package top.xtcoder.xtpsd.core.image.resources;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import top.xtcoder.xtpsd.core.image.resources.handle.I1028ResourceCallback;
import top.xtcoder.xtpsd.core.image.resources.handle.I1060ResourceCallback;
import top.xtcoder.xtpsd.core.image.resources.handle.I1061ResourceCallback;
import top.xtcoder.xtpsd.core.image.resources.handle.IResourceCallback;
import top.xtcoder.xtpsd.core.image.resources.vo.ImageResource;
import top.xtcoder.xtpsd.core.image.resources.vo.PsdImageResources;
import top.xtcoder.xtpsd.utils.ByteUtil;

public class ImageResourceParse {
	
	private InputStream inputStream;
	
	public PsdImageResources parse(FileInputStream fis) throws IOException {
		PsdImageResources imageResource = new PsdImageResources();
		long irlLength = readImageResourceLength(fis, imageResource);
		long imageResourceLength = readImageResource(imageResource);
		
		System.out.println("图像资源长度字节数： " + irlLength + ", length解析字节数: " + imageResource.getImageResourceLength() + ", 图像资源实际读取字节数：" + imageResourceLength);
		return imageResource;
	}
	
	private long readImageResourceLength(
			FileInputStream fis,
			PsdImageResources imageResource) throws IOException {
		long readSize = 0;
		byte[] bsImageResourceLength = new byte[4];
		readSize += fis.read(bsImageResourceLength);
		int imageResourceLength = ByteUtil.bytesToInt(bsImageResourceLength);
		imageResource.setImageResourceLength(imageResourceLength);
		
		byte[] imageBytes = new byte[imageResourceLength];
		fis.read(imageBytes);
		inputStream = new ByteArrayInputStream(imageBytes);
		
		return readSize;
	}
	
	private long readImageResource(
			PsdImageResources imageResource) throws IOException {
		
		int readImageResourceLength = 0;
		List<ImageResource> imageResources = new ArrayList<>();
		while(readImageResourceLength < imageResource.getImageResourceLength()) {
			
			byte[] bsIrbSign = new byte[4];
			readImageResourceLength += inputStream.read(bsIrbSign);
			
			byte[] bsIrbResourceIds = new byte[2];
			readImageResourceLength += inputStream.read(bsIrbResourceIds);
			int irbResourceId = ByteUtil.bytesToInt(bsIrbResourceIds);
			
			ImageResource ir = new ImageResource();
			ir.setSignature(new String(bsIrbSign));
			ir.setImageResourceID(irbResourceId);
			
			byte[] bsIrbNameLength = new byte[1];
			readImageResourceLength += inputStream.read(bsIrbNameLength);
			int nLength = ByteUtil.bytesToInt(bsIrbNameLength);
			ir.setNameLength(nLength);
			
			if(nLength == 0) {
				readImageResourceLength += 1;
				ByteUtil.readByteToStr(inputStream, 1);
			}else if(nLength % 2 != 0) {
				//为奇数：末尾追加一个0
				readImageResourceLength += nLength;
				String irbName = ByteUtil.readByteToStr(inputStream, nLength);
				ir.setName(irbName);
				
				readImageResourceLength += 1;
				ByteUtil.readByteToStr(inputStream, 1);
			}else {
				byte[] bsIrbName = new byte[nLength];
				readImageResourceLength += inputStream.read(bsIrbName);
				ir.setName(new String(bsIrbName));
			}
			
			byte[] bsIrbSize = new byte[4];
			readImageResourceLength += inputStream.read(bsIrbSize);
			int resourceDataLength = ByteUtil.bytesToInt(bsIrbSize);
			ir.setResourceDataLength(resourceDataLength);
			if(resourceDataLength > 0) {
				byte[] bsData;
				if(resourceDataLength % 2 != 0) {
					//为奇数：末尾追加一个0
					bsData = new byte[resourceDataLength];
					readImageResourceLength += inputStream.read(bsData);
					
					byte[] bsDataEnd0 = new byte[1];
					readImageResourceLength += inputStream.read(bsDataEnd0);
					
					ir.setResourceDataEnd(bsDataEnd0);
				}else {
					bsData = new byte[resourceDataLength];
					readImageResourceLength += inputStream.read(bsData);
				}
				Map<String, Object> rd = handleResourceData(irbResourceId, bsData);
				ir.setResourceData(rd);
			}
			imageResources.add(ir);
		}
		imageResource.setImageResources(imageResources);
		
		return readImageResourceLength;
	}
	
	private Map<String, Object> handleResourceData(int irbResourceId, byte[] bsData) {
		Map<String, IResourceCallback> handles = getResourceDataHandles();
		IResourceCallback rc = handles.get(String.valueOf(irbResourceId));
		if(rc != null) {
			return rc.handle(bsData);
		}
//		System.out.println("资源" + irbResourceId + " 还未处理");
		return null;
	}
	
	private Map<String, IResourceCallback> getResourceDataHandles() {
		Map<String, IResourceCallback> handles = new HashMap<>();
//		handles.put("1028", new I1028ResourceCallback());
//		handles.put("1061", new I1061ResourceCallback());
		handles.put("1060", new I1060ResourceCallback());
		return handles;
	}
}
